Java Stream API常用操作方法
总结
- Stream 操作分两类:中间操作(惰性,返回 Stream)和终止操作(触发计算,返回结果)
- 常用:filter 过滤、map 映射、groupingBy 分组、sorted 排序、distinct 去重
- Stream 不能复用;数据量小时和 for 循环性能差不多,别过度优化
Stream 操作分两类:
- 中间操作(返回 Stream):filter、map、sorted 等,惰性执行
- 终止操作(返回结果):collect、count、reduce 等,触发实际计算
1. 过滤 filter
// 单条件
List<User> failed = list.stream()
.filter(u -> u.getScore() < 60)
.collect(Collectors.toList());
// 多条件
List<User> result = list.stream()
.filter(u -> u.getScore() >= 60 && u.getGrade() == 1)
.collect(Collectors.toList());
2. 映射 map
// 提取字段列表
List<String> names = list.stream()
.mapgetName
.collect(Collectors.toList());
List<Integer> ids = list.stream()
.mapgetId
.collect(Collectors.toList());
3. 排序 sorted
// 升序
list.streamgetId);
// 降序
list.streamgetId).reversed();
4. 去重 distinct
// 基于 equals() 去重,记得重写 equals 和 hashCode
list.stream().distinct().collect(Collectors.toList());
5. 统计
// 求和
double sum = list.streamgetScore).sum(;
// 平均值
double avg = list.streamgetScore).average().orElse(0.0;
// 计数
long count = list.stream().filter(u -> u.getScore() >= 60).count();
6. 分组 groupingBy
// 按年级分组
Map<Integer, List<User>> byGrade = list.stream()
.collectgetGrade);
// 多重分组:年级 → 班级
Map<Integer, Map<Integer, List<User>>> byGradeAndClass = list.stream()
.collect(Collectors.groupingBy(
User::getGrade,
Collectors.groupingBygetClasses
));
// 分组统计每个年级人数
Map<Integer, Long> countByGrade = list.stream()
.collectgetGrade, Collectors.counting());
// 分组统计每个年级总分
Map<Integer, Double> sumByGrade = list.stream()
.collect(Collectors.groupingBy(
User::getGrade,
Collectors.summingDoublegetScore
));
7. 常用 Collectors
Collectors.toList() // → List
Collectors.toSet() // → Set
Collectors.toMapgetId, User::getName // → Map
Collectors.joining(", ") // 拼接字符串
Collectors.partitioningBy(u -> u.getScore() >= 60) // 按 boolean 分两组
Collectors.maxBygetScore) // 最大值
8. 链式组合示例
// 每个年级及格人数
Map<Integer, Long> passCount = list.stream()
.filter(u -> u.getScore() >= 60)
.collectgetGrade, Collectors.counting());
// 每个年级分数最高的学生
Map<Integer, Optional<User>> topByGrade = list.stream()
.collect(Collectors.groupingBy(
User::getGrade,
Collectors.maxBygetScore)
));
9. 几个注意点
- Stream 用完就关闭,不能复用,需要重新从集合创建
- 数据量小时 Stream 和 for 循环性能差不多,别过度优化
parallelStream()可以多核并行,但要注意线程安全,不是所有场景都适合